package middleware

import (
	"bytes"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"io"
)

type logMiddlewareBuilder struct {
	logger *zap.Logger
	input  bool
}

func NewLogMiddlewareBuilder(logger *zap.Logger) *logMiddlewareBuilder {
	return &logMiddlewareBuilder{
		logger: logger,
		input:  false,
	}
}

func (l *logMiddlewareBuilder) LogInput() *logMiddlewareBuilder {
	l.input = true
	return l
}

func (l logMiddlewareBuilder) Build() gin.HandlerFunc {
	return func(c *gin.Context) {
		url := c.Request.URL.String()
		if len(url) > 1024 {
			url = url[:1024]
		}
		al := accessLog{
			Method: c.Request.Method,
			Url:    url,
		}
		if l.input {
			body, _ := io.ReadAll(c.Request.Body)
			// Body 是 Stream，所以只能读一次
			// 所以要放回去
			c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
			al.Body = string(body)
		}
		defer func() {
			al.MatchedRoute = c.FullPath()
			l.logger.Info("收到请求", zap.Any("req", al))
		}()

		// 跑过去业务逻辑里面
		c.Next()
	}
}

type accessLog struct {
	Method string
	Url    string
	// 命中的路由
	MatchedRoute string

	// 要不要记录请求 body 呢？
	Body string
}
